-
Notifications
You must be signed in to change notification settings - Fork 173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial touch driver #346
base: master
Are you sure you want to change the base?
Initial touch driver #346
Conversation
src/touch.rs
Outdated
Ok(TouchDriver {}) | ||
} | ||
|
||
pub fn init(&mut self) -> Result<(), EspError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in some drivers there is a compelling reason to split init from the creation of the driver - but is this the case for the touch driver? Same goes for calling the config step separately. I think it would be nicer to just call TouchDriver::new(&some_config)?; and be done with all initial steps. Reducing the api surface the user needs to interact on and less chance to do things out of order.
In othere words combine new / init / config into one pub api call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea happy to consolidated new + init + config, should the FSM stuff go in there as well? I'm not sure I quite understand what it does...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if its a onetime config that is not supposed to be changed after init, i also would combine it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmm in the case that the FSM mode is set to software a different start function should be used, not sure I'm understanding it right but seem that the point of this is so you can control when it starts in software, and so maybe it shouldn't be part of new
? Or have I misunderstood?
Because the touch-driver only works on xtensa based esp you need to gate the complete module against the esp32 / esp32s2 /esp32s3 , otherwise its a build errror for the riscv esp's |
Looks like esp32 has a different touch api from s2/s3, so my inclination is to restrict this PR to the later, wdyt @Vollbrecht ? |
to my understanding, there is an old touch_api only for the esp32, and a newer one that works on all 3 chips. So you probably only use the newer one that can be used by all chips |
Compile against esp32 seems to be failing as the APIs are different though? |
you need to use the common header api. here this header definitions is shared across all 3. There might be that there are some specific implementations that are only part of one version for example for the s3 that are not found in the othere. But you can implement the basic common set first for all |
And if you use something out of a specific driver than you need to make sure to gate it to the specific esp, you can than search in the othere drivers if they have similar functions but just use them slighty different. You could try to unifiy it with one pub api and internally just use conditional compilation to get a similar feature set |
as long as esp-idf-sys is not release with the touch-driver exposed you also need to use a patch.crates-io inside the Cargo.toml to point to the current esp-idf-sys master version, so CI can build it |
Ok, I don't have an esp32 so wont be able to test any branches that are for that chip only so my concern is I'll basically be guessing as to what the right logic is in that case |
src/touch.rs
Outdated
|
||
pub struct TouchConfig { | ||
fsm_mode: FsmMode, | ||
configured_pads: Vec<TouchPad>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Vec
seems to be causing build issues, not sure how best to resolve?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you start collecting all the pads in one struct anyway. In the end from a design perspective it will be problematic, for example if you want to set or read a pin, or if you want to create an ISR/callback for it, you somehow need to be able to address that pin. So a general approach would be here similar to the PinDriver - where each PinDriver is one instance tight to one gpio pin.
If you have problems that some part of the api should only be called once like some of the init code we maybe need to split them of ( need to find that out) - in that case we would have something like a TouchDriver that would do the innit and config stuff - and then something like a TouchPadDriver for each individual pad to get to the individual get / set methods etc. Otherwise if thats not a problem just go with one struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So init
is universal so I think we will need both, how do you envisage TouchDriver
and TouchPadDriver
interacting? Create the latter from a method on the former? The FSM stuff is also universal and I'm not sure if that needs to be called after conflagration of individual pads?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one thing we care about is cleaning up behind ourself automatically. So if a PadDriver goes out of scope it needs to be dropped correctly. We could make it that a TouchPadDriver gets a &TouchDriver and so it gets the lifetime of it intrinsically. Also you need to make sure to implement Drop correctly on both, so if TouchDriver gets out of scope the driver gets de-init correctly in reverse order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still not totally clear on what's needed here, is there analogous code in some other driver I could look at for inspiration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example in the SpiDriver - you can have one spi setup that service multiple connected spi-devices with for example different chip-select lines. So you are creating one overall SpiDriver and for each device you want to use it for you create an SpiDeviceDriver from a concept it would here be similar, though notice because that we have a lot of cases in spi the driver itself is somewhat complicated, so you dont need to try to understand how it works there - just how the concept works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, updated to mimic the approach of SpiDriver, lmk what you think
just go with the common api for now that is shared between all and you should be good. After that you can try to play with the specific stuff |
don't forget to run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you see the clippy warning in the CI for the normal esp32. The return type of the implementation on esp32 is different. You need to handle this case with a conditional compilation.
Since the touch module itself is already scoped to esp32 -esp32s3 i think the #[cfg(any(esp32, esp32s2, esp32s3))]
on each codeblock could be removed since the compiler should not look here in other cases.
I've disabled for esp32 as I dont have the ability to test against that, so figured keeping things simpler will be easier for me as I'm new to all this |
|
||
impl TouchPadDriver<TouchDriver> { | ||
pub fn new_single_started(pad: TouchPad, config: TouchConfig) -> Result<Self, EspError> { | ||
let mut touch = TouchDriver::new(config)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
crating the TouchDriver inside the TouchPadDriver makes little sense, ( Sorry i hope i am not rude here ;D ) You can explain your thinking here.
My thinking: As in this case you wouldn't even need all the TouchDriver buisness in the first place. Its fine to create two different version of TouchPadDriver, one with new() and one with new_single(). Where the first one takes a reference to the TouchDriver that is created before so multiple TouchPadDrivers can be created, and in the later case it takes an owned value of TouchDriver, where one would only ever use on pin.
Very basic wrapper around small portion of the API surface to start with, keen to get feedback on how to evolve.
Closes #342